home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Disc to the Future 2
/
Disc to the Future Part II Programmer's Reference (Wayzata Technology)(6013)(1992).bin
/
MAC
/
MPW_TOOL
/
TOOLS
/
TOOLS_WI
/
ICON_8
/
MEMMON_F
/
MCONTROL.C
< prev
next >
Wrap
Text File
|
1990-03-02
|
9KB
|
278 lines
/*
* mcontrol.c: main control of memory monitoring.
*/
#include "memmon.h"
hidden novalue gcmark Params((word n));
static units;
static pausereply = 0;
static initialized = 0;
/*
* skipgc(n) - skip the first n garbage collections.
*/
novalue skipgc(n)
int n;
{
int b, c;
if (gclimit == 0)
mquit(NormalExit);
b = 0;
while (n > 0) {
switch (c = getc(ifile)) {
case EOF: /* EOF */
fprintf(stderr, "%s: hit EOF while skipping\n", progname);
exit(ErrorExit);
return;
case '#': /* comment */
case ';': /* pause */
while ((c = getc(ifile)) != EOF && c != '\n')
;
break;
case '{':
ncollect++;
switch (b - '0') {
case 4: /* fall through -- old version of case 0 */
case 0: nexplicit++; break;
case 1: nstatic++; break;
case 2: nstring++; break;
case 3: nblock++; break;
}
if (ncollect == gclimit)
mquit(NormalExit);
break;
case '}': /* end marking phase */
n--;
break;
}
b = c;
}
}
/*
* memmon() - main loop of the memory monitor.
*/
novalue memmon()
{
int c;
word addr, len;
int colr;
char buf[LineSize];
if (pauselimit == 0)
return;
for (;;) switch (c = getcmd(&addr, &len)) {
case 0: /* 0: end of file; terminate cleanly */
if (!initialized) {
fprintf(stderr, "%s: empty input file\n", progname);
exit(ErrorExit);
}
mpause('d', "done");
mstatus("done", C_Status);
return;
case '#': /* #: comment */
while ((c = getc(ifile)) != EOF && c != '\n')
;
break;
case '<': /* <: new memory layout */
units = (len > 0) ? len : 4; /* set units if specified */
getregion(&stc);
getregion(&str);
getregion(&blk);
refresh(); /* redraw entire screen */
str.used = 0; /* will recalculate during marking */
blk.used = 0;
paintblk(&stc, (word)0, stc.length, C_Free);
paintstr((word)0, str.length, C_Free, C_Bsep);
paintblk(&blk, (word)0, blk.length, C_Free);
if (ncollect > 0)
mstatus("compacting", C_Status);
initialized = 1;
break;
case '>': /* >: new layout is complete */
mstatus("running", C_Status);
devflush();
break;
case '=': /* =: check that we're in sync */
rsync(&stc, "static");
rsync(&str, "string");
rsync(&blk, "blk");
break;
case '"': /* ": string allocation */
paintstr(str.used, len, Unmarked + C_String, Unmarked + C_Ssep);
str.used += len;
break;
case '$': /* $: mmshow() of a string */
colr = getshow();
paintstr(addr, len, colr, Unmarked + C_Ssep);
break;
case 'u': /* u: Tvsubs substring trapped var */
case 'f': /* f: T_File file block */
case 'x': /* x: T_Refresh refresh block */
case 'i': /* i: T_Bignum long integer */
case 'r': /* r: T_Real real number */
case 'R': /* R: T_Record record block */
case 'S': /* S: T_Set set header block */
case 's': /* s: T_Selem set element block */
case 'L': /* L: T_List list header block */
case 'l': /* l: T_Lelem list element block */
case 'T': /* T: Table table header block */
case 't': /* t: Telem table element block */
case 'h': /* h: T_Slots hash buckets (slots) */
case 'e': /* e: Tvtbl table elem trapped var */
case 'E': /* E: T_External external block */
case 'c': /* c: T_Cset cset */
len *= units;
paintblk(&blk, blk.used, len, Unmarked + blkcolor[c]);
blk.used += len;
break;
case '%': /* %: mmshow() in the block region */
addr *= units;
len *= units;
colr = getshow();
paintblk(&blk, addr, len, colr);
break;
case 'A': /* A: alien block in static region */
case 'F': /* F: free block in static region */
addr *= units;
len *= units;
paintblk(&stc, addr, len, blkcolor[c]);
break;
case 'X': /* X: coexpr block in static region */
addr *= units;
len *= units;
paintblk(&stc, addr, len, Unmarked + blkcolor[c]);
break;
case 'Y': /* Y: mmshow() in the static region */
addr *= units;
len *= units;
colr = getshow();
paintblk(&stc, addr, len, colr);
break;
case ';': /* ;: mmpause() call */
getc(ifile); /* skip space character */
fgets(buf, LineSize, ifile); /* read message */
buf[strlen(buf)-1] = '\0'; /* remove newline */
/* pause unless previous reply said "don't stop again" */
if (pausereply != EOF && pausereply != 'g' && pausereply != 'G')
pausereply = mpause('p', buf);
break;
case '{': /* {: begin marking for garb. coll. */
gcmark(len);
break;
case '!': /* !: end garbage collection */
gcwait('c', "end garbage collection");
if (ncollect == gclimit) {
mstatus("quit", C_Status);
mquit(NormalExit);
}
mstatus("running", C_Status);
break;
default:
fprintf(stderr, "%s: unexpected input char: %c\n", progname, c);
exit(ErrorExit);
}
}
/*
* gcmark(n) - handle marking phase of garbage collection, reason n.
*/
static novalue gcmark(n)
word n;
{
word addr, len;
int c, markflag;
char *s;
markflag = showmarking;
ncollect++;
switch ((int)n) {
case 4: /* fall through -- old version of case 0 */
case 0: s = "collect(0) call"; nexplicit++; break;
case 1: s = "need static space"; nstatic++; break;
case 2: s = "need string space"; nstring++; break;
case 3: s = "need block space"; nblock++; break;
default: s = "g.c. reason lost"; break;
}
if (gcwait('f', s) == '+')
markflag = 0;
if (markflag)
mstatus("marking", C_Status);
for (;;) switch (c = getcmd(&addr, &len)) {
case '#': /* #: comment */
while ((c = getc(ifile)) != EOF && c != '\n')
;
break;
case 0: /* 0: end of file (shouldn't happen) */
case '}': /* }: end marking phase */
if (markflag)
do {
c = gcwait('g', "marking done, garbage remains");
if (c == EOF || !index(whenpause, 'a'))
break;
setmap(Unmarked, C_Unmarked);
c = gcwait('a', "active data before compaction");
setmap(Marked, C_Marked);
} while (c == '-');
return;
case '"': /* ": string allocation */
if (markflag)
paintstr(addr, len, Marked + C_String, Marked + C_Ssep);
break;
case 'u': /* u: Tvsubs substring trapped var */
case 'f': /* f: T_File file block */
case 'x': /* x: T_Refresh refresh block */
case 'i': /* i: T_Bignum long integer */
case 'r': /* r: T_Real real number */
case 'R': /* R: T_Record record block */
case 'S': /* S: T_Set set header block */
case 's': /* s: T_Selem set element block */
case 'L': /* L: T_List list header block */
case 'l': /* l: T_Lelem list element block */
case 'T': /* T: Table table header block */
case 't': /* t: Telem table element block */
case 'e': /* e: Tvtbl table elem trapped var */
case 'h': /* h: T_Slots hash buckets (slots) */
case 'E': /* E: T_External external block */
case 'c': /* c: T_Cset cset */
if (markflag) {
addr *= units;
len *= units;
paintblk(&blk, addr, len, Marked + blkcolor[c]);
}
break;
case 'A':
case 'F':
case 'X':
if (markflag) {
addr *= units;
len *= units;
paintblk(&stc, addr, len, Marked + blkcolor[c]);
}
break;
default:
fprintf(stderr,"%s: unexpected input char during gc: %c\n",progname,c);
exit(ErrorExit);
}
}